<script setup lang="ts">
import { nextTick, onMounted, reactive, ref } from 'vue'
import { addCategory, deleteCategories, queryAllCategories, updateCategory } from '@/api/category'
import type { CategoryVo } from '@/api/category/type'
import type { FormInstance, FormRules } from 'element-plus'
import { ElMessage, ElTree } from 'element-plus'
import { useUserStore } from '@/stores/userStore'

// 分类集合
const categoryVos = ref<CategoryVo[]>()
// 页面加载后查询分类信息，以树形结构返回
onMounted(async () => {
  await queryAllCategories()
    .then((res) => {
      categoryVos.value = res
    })
    .catch((err) => console.log(err))
})
const defaultProps = {
  children: 'children',
  label: 'name',
}
// 控制对话框的显示和隐藏(false:隐藏，true:显示)
const dialogVisible = ref(false)
let categoryVo = ref<CategoryVo>({
  categoryID: 0,
  name: '',
  parentCID: 0,
  catLevel: 0,
  showStatus: false,
  sort: 1,
  icon: '',
  productUnit: '',
  productCount: 0,
  children: [],
})
// 增加分类按钮单击事件
const append = (data: CategoryVo) => {
  categoryVo = ref<CategoryVo>({
    categoryID: 0,
    name: '',
    parentCID: 0,
    catLevel: 0,
    showStatus: false,
    sort: 1,
    icon: '',
    productUnit: '',
    productCount: 0,
    children: [],
  })
  dialogVisible.value = true
  categoryVo.value.parentCID = data.categoryID
  categoryVo.value.catLevel = data.catLevel
  // 清除校验信息
  nextTick(() => {
    ruleFormRef.value.clearValidate('name')
  })
}
const ruleFormRef = ref<FormInstance>()
const rules = reactive<FormRules<CategoryVo>>({
  name: [
    { required: true, message: '请输入分类名称', trigger: 'blur' },
    { min: 2, max: 50, message: '分类名称在2到50之间', trigger: 'change' },
  ],
})
// 确定保存按钮单击事件
const save = () => {
  // 若校验通过，则发送保存分类请求
  ruleFormRef.value.validate(async (valid: boolean) => {
    if (valid) {
      if (categoryVo.value.categoryID === 0) {
        await addCategory(categoryVo.value)
          // 添加成功之后重新查询分类信息
          .then(() => {
            ElMessage({
              message: '添加成功',
              type: 'success',
            })
            return queryAllCategories()
          })
          .then((res) => {
            categoryVos.value = res
          })
          .catch((err) => {
            console.log(err)
          })
      } else {
        // 若id不为零，则发送修改数据请求`
        await updateCategory(categoryVo.value)
          // 修改成功之后重新查询分类信息
          .then(() => {
            ElMessage({
              message: '修改成功',
              type: 'success',
            })
            return queryAllCategories()
          })
          .then((res) => {
            categoryVos.value = res
          })
          .catch((err) => {
            console.log(err)
          })
      }

      dialogVisible.value = false
    }
  })
}
// 分类id集合
const categoryIds = ref<number[]>([])
// 默认展开的节点id
const defaultExpandIds = ref<number[]>([])
const remove = (node: Node, data: CategoryVo) => {
  // 设置默认展开的数组
  defaultExpandIds.value.push(data.parentCID)
  // 将要删除的分类的id集合
  categoryIds.value.push(data.categoryID)
}
// 确定删除按钮单击事件
const onConfirm = async () => {
  // 删除分类信息
  await deleteCategories(categoryIds.value)
    // 删除之后重新查询分类信息
    .then(() => {
      ElMessage({
        message: '删除成功',
        type: 'success',
      })
      return queryAllCategories()
    })
    .then((res) => {
      categoryVos.value = res
    })
    .catch((err) => {
      console.log(err)
    })
}
// 修改按钮单击事件
const update = (data: CategoryVo) => {
  dialogVisible.value = true
  Object.assign(categoryVo.value, data)
  // 清除校验信息
  nextTick(() => {
    ruleFormRef.value.clearValidate('name')
  })
}
// 树实例
const treeRef = ref<InstanceType<typeof ElTree>>()
// 批量删除
const batchDelete = async () => {
  categoryIds.value = treeRef.value!.getCheckedKeys(true)
  await deleteCategories(categoryIds.value)
    .then(() => {
      ElMessage({
        message: '删除成功',
        type: 'success',
      })
      return queryAllCategories()
    })
    .then((res) => {
      categoryVos.value = res
    })
    .catch((err) => {
      console.log(err)
    })
}
// 引入用户仓库
const userStore = useUserStore()
const buttons = userStore.buttons
</script>

<template>
  <div class="container">
    <el-button
      type="danger"
      style="margin-bottom: 1rem"
      @click="batchDelete"
      v-if="buttons?.includes('DeleteCategory')"
    >
      批量删除
    </el-button>
    <!--    以树形结构显示分类信息-->
    <el-tree
      :data="categoryVos"
      show-checkbox
      :props="defaultProps"
      :expand-on-click-node="false"
      node-key="categoryID"
      ref="treeRef"
    >
      <template #default="{ node, data }">
        <div class="custom-tree-node">
          <span>{{ node.label }}</span>
          <div>
            <el-button
              v-if="data.catLevel <= 2 && buttons?.includes('AddCategory')"
              type="primary"
              plain
              @click="append(data)"
            >
              新增
            </el-button>
            <el-button @click="update(data)" v-if="buttons?.includes('EditCategory')">
              修改
            </el-button>
            <el-popconfirm title="确定要删除吗?" @confirm="onConfirm">
              <template #reference>
                <el-button
                  v-if="data.children.length === 0 && buttons?.includes('DeleteCategory')"
                  type="danger"
                  @click="remove(node, data)"
                >
                  删除
                </el-button>
              </template>
            </el-popconfirm>
          </div>
        </div>
      </template>
    </el-tree>
    <!--    增加及修改分类的弹框-->
    <el-dialog
      v-model="dialogVisible"
      :title="categoryVo.categoryID == 0 ? '新增' : '修改' + '分类'"
      style="width: 30rem"
    >
      <el-form :model="categoryVo" ref="ruleFormRef" :rules="rules">
        <el-form-item label="分类名称" prop="name">
          <el-input placeholder="请输入分类名称" v-model="categoryVo.name"></el-input>
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="dialogVisible = false">取消</el-button>
          <el-button type="primary" @click="save">确定</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<style scoped>
.container {
  padding: 1rem 3rem;

  .custom-tree-node {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: space-between;
    font-size: 1rem;
  }
}
</style>
